using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Configuration.Install;
using System.Reflection;
using System.Windows.Forms;
using System.Data.SqlClient;
using Microsoft.Vsts.Ranger.Migration.TfsToTfs.Client;
using System.Xml.Serialization;
using System.IO;
using System.Threading;
using Microsoft.Vsts.Ranger.Migration.TfsToTfs.Service.Common;

namespace Microsoft.Vsts.Ranger.Migration.TfsToTfs.Client.Install
{
    [RunInstaller(true)]
    public partial class InstallerConfig : Installer
    {
        private const string  TOOLKIT_CONFIG_FILENAME = "TfsToTfsMigrationToolConfig.xml";
        private const string windowsServiceConnectStringName = "TfsMigrationService.Properties.Settings.TPCopyLoggingConnectionString";
        private InstallContext installContext;
        private string assemblyLocation;
        private string installFolder;

        public InstallerConfig()
        {
            InitializeComponent();
            assemblyLocation = Assembly.GetExecutingAssembly().Location;
            installFolder = Directory.GetParent(assemblyLocation).FullName;
            this.installContext = new InstallContext(Path.Combine(installFolder, "InstallLog.txt"), null);

        }

        public override void Install(System.Collections.IDictionary stateSaver)
        {
            try
            {
                this.installContext.LogMessage("Running UI Installer Class...");

                base.Install(stateSaver);


                System.Configuration.Configuration config =
                 ConfigurationManager.OpenExeConfiguration(assemblyLocation);

                //Change the config to use the windows service host
                config.AppSettings.Settings["SelfHostService"].Value = "False";

                //Get the connect string from the other assembly config
                string connectString = ConfigurationManager.OpenExeConfiguration(Path.Combine(installFolder, "TfsMigrationWindowsServiceHost.exe")).ConnectionStrings.ConnectionStrings[windowsServiceConnectStringName].ConnectionString;

                //Save the connect to this assembly's config
                config.ConnectionStrings.ConnectionStrings[windowsServiceConnectStringName].ConnectionString = connectString;

                config.Save(ConfigurationSaveMode.Modified);

                //CreateTempFolder();  Don't need this now, using %TEMP% in config

                UpdateSessionFileDatabaseSettings(connectString);

                try
                {
                    System.ServiceProcess.ServiceController controller = new System.ServiceProcess.ServiceController(Constants.CMIGRATIONSERVICENAME);
                    controller.Start();
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Service Could Not Be Started Manually.  Please start Tfs to Tfs Migration Service Windows service manually before running application.  Error Starting:" + ex.Message);
                }
            }
            catch (Exception ex)
            {
                this.installContext.LogMessage("An Error Has Occurred.  Check The Install Log: " + ex.Message);
                throw;
            }
        }

        [Obsolete]
        private void CreateTempFolder()
        {
            if(Directory.Exists("c:\\temp"))
            {
                //Create a temp folder if one doesnt yet exist, for the log file
                Directory.CreateDirectory("c:\\temp");
            }
        }
        private void UpdateSessionFileDatabaseSettings(string connectString)
        {
            try
            {
                this.installContext.LogMessage("Updating toolkit configuration file...");

                SqlConnectionStringBuilder connectBuilder = new SqlConnectionStringBuilder(connectString);

                //Remove the instance name if one is there (e.g. localhost\instanceName)
                string serverName = connectBuilder.DataSource.Split("\\".ToCharArray())[0];

                if (serverName == ".")
                    serverName = "localhost";

                connectBuilder.InitialCatalog = "";

                XmlSerializer ser = new XmlSerializer(typeof(MigrationConfig.MigrationElement));

                MigrationConfig.MigrationElement migrationConfig;

                string configFilePath = Path.Combine(Directory.GetParent(Assembly.GetExecutingAssembly().Location).FullName, TOOLKIT_CONFIG_FILENAME);

                //Read in the config file
                using (TextReader reader = File.OpenText(configFilePath))
                {
                    migrationConfig = (MigrationConfig.MigrationElement)ser.Deserialize(reader);
                }

                //Update the config file settings
                migrationConfig.Sql.ConnectionString = connectBuilder.ConnectionString;
                migrationConfig.Sql.Server = serverName;


                //Delete the old file so that the new one can be written
                if (File.Exists(configFilePath))
                    File.Delete(configFilePath);

                //Write the config file back out
                using (TextWriter outStream = File.CreateText(configFilePath))
                {
                    ser.Serialize(outStream, migrationConfig);

                    outStream.Close();
                }

            }
            catch (Exception ex)
            {
                string message = "Error writing to Toolkit configuration file to update the SQL Server name and connect string.  File name is " + TOOLKIT_CONFIG_FILENAME + " Error Message: " + ex.Message;

                MessageBox.Show(message);

                this.installContext.LogMessage(message);

            }

        }
    }
}